package org.manon.json.asm.ser;

import static org.manon.json.asm.ASMUtil.TYPE_SERIALIZER_PROVIDER;
import static org.manon.json.asm.ASMUtil.TYPE_VOID;

import java.util.Arrays;

import org.manon.json.asm.ASMBaseGenerator;
import org.manon.json.asm.ASMContextSerializer;
import org.manon.json.asm.ASMSerializer;
import org.manon.json.asm.MethodVisitorTemplate;
import org.manon.json.meta.Entity;
import org.manon.json.util.ClassUtils;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

public class CreateConstructorTemplate extends MethodVisitorTemplate<ASMContextSerializer> {

	private final ASMBaseGenerator _generator;
	
	public CreateConstructorTemplate(ASMBaseGenerator generator) {
		super(Opcodes.ACC_PUBLIC, "<init>", Type.getMethodDescriptor(TYPE_VOID,TYPE_SERIALIZER_PROVIDER), null, null);
		_generator = generator;
	}
	/**
	 * @see org.manon.json.asm.MethodVisitorTemplate#doCreate(org.manon.json.asm.ASMContextSerializer, org.objectweb.asm.MethodVisitor)
	 */
	@Override
	protected void doCreate(ASMContextSerializer context, MethodVisitor methodVisitor) throws Exception {
		final String[] path = ClassUtils.path(context.getEntity().getEntityClass());
		methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
		
		if (path.length == 1) {
			methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL,Type.getInternalName(ASMSerializer.class),"<init>",Type.getMethodDescriptor(TYPE_VOID));
		} else{
			Entity entity = _generator.getRegistry().search(Arrays.copyOfRange(path,0,path.length-1));
			methodVisitor.visitVarInsn(Opcodes.ALOAD, 1);
			methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL,entity.getInternalClassNameForSerializer(),"<init>",Type.getMethodDescriptor(TYPE_VOID, TYPE_SERIALIZER_PROVIDER));
		}
		context.appendToConstructor(methodVisitor);
	}

}